/*
 * @Author: 0x9DEFA478
 * @Date: 2021-10-09 17:45:27
 * @LastEditTime: 2021-10-11 17:46:22
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "IC_Mifare1.h"


// ISO14443 TypeA

#define vIC_Mifare1_CMD_REQA                      0x26U              //卡探测指令 探测空闲状态的卡
#define vIC_Mifare1_CMD_WUPA                      0x52U              //卡探测指令 探测全部卡
#define vIC_Mifare1_CMD_SEL_Level1                0x93U              //防冲撞1
#define vIC_Mifare1_CMD_SEL_Level2                0x95U              //防冲撞2
#define vIC_Mifare1_CMD_SEL_Level3                0x97U              //防冲撞3
#define vIC_Mifare1_CMD_HLTA                      0x50U              //休眠


// Mifare1

#define vIC_Mifare1_CMD_AuthentA                  0x60U              //验证A密钥
#define vIC_Mifare1_CMD_AuthentB                  0x61U              //验证B密钥
#define vIC_Mifare1_CMD_Read                      0x30U              //读块
#define vIC_Mifare1_CMD_Write                     0xA0U              //写块
#define vIC_Mifare1_CMD_Decrement                 0xC0U              //扣款
#define vIC_Mifare1_CMD_Increment                 0xC1U              //充值
#define vIC_Mifare1_CMD_Restore                   0xC2U              //调块数据到缓冲区
#define vIC_Mifare1_CMD_Transfer                  0xB0U              //保存缓冲区中数据






//============================================================================================================================================
//
// 私有方法
//
//============================================================================================================================================

//初值0x6363 数据的字节低位为被除数的高位 多项式 0x1021
static Huint16 CalculateCRC(Hbyte* SrcData,Hbyte Length){
  int i;
  Huint16 r;

  r=0x6363U;
  while(Length>0){
    Length--;

    r^=(Huint16)SrcData[0];
    for(i=0;i<8;i++){
      if((r&0x1U)!=0x0U){
        r=(r>>1)^0x8408U;//低位为除数的高位 0x1021需要位翻转为0x8408
      }else{
        r=r>>1;
      }
    }

    SrcData=&SrcData[1];
  }

  return r;
}

//初值0x6363 数据的字节低位为被除数的高位 多项式 0x1021
static void CalculateCRC_ToArray(Hbyte* SrcData,Hbyte Length,Hbyte* CRC_Result){
  Huint16 r;

  r=CalculateCRC(SrcData,Length);

  CRC_Result[0]=(Hbyte)(r&0xFFU);
  CRC_Result[1]=(Hbyte)((r>>8)&0xFFU);
}

//卡探测
static int Request(IC_Mifare1* _this,int IsAll,Huint16* ATQA){

  Hbyte TxRxBuffer[2];
  Hbyte RxBitLength;
  int Result;


  if(IsAll==0){
    TxRxBuffer[0]=vIC_Mifare1_CMD_REQA;
  }else{
    TxRxBuffer[0]=vIC_Mifare1_CMD_WUPA;
  }

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,7U,TxRxBuffer,16U,&RxBitLength,25);
  if(Result!=vIC_Mifare1_Result_Ok){
    return Result;
  }

  if(RxBitLength!=16U){
    return vIC_Mifare1_Result_Error;
  }

  ATQA[0]=(((Huint16)TxRxBuffer[0])&0x00FF)|((((Huint16)TxRxBuffer[1])<<8)&0xFF00);

  return Result;
}

//该方法不支持多卡同时存在下的ID获取(实际应用中几乎不需要多卡同时识别)
static int Anticollision_Sub(IC_Mifare1* _this,Hbyte CMD_Anticollision,Hbyte* Data){
  Hbyte TxRxBuffer[5];
  Hbyte RxBitLength;
  int Result;

  TxRxBuffer[0]=CMD_Anticollision;
  TxRxBuffer[1]=0x20U;

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,16U,TxRxBuffer,40U,&RxBitLength,25);
  if(Result==vIC_Mifare1_Result_Ok){
    if(RxBitLength==40U){

      Data[0]=TxRxBuffer[0];
      Data[1]=TxRxBuffer[1];
      Data[2]=TxRxBuffer[2];
      Data[3]=TxRxBuffer[3];

      if((TxRxBuffer[0]^TxRxBuffer[1]^TxRxBuffer[2]^TxRxBuffer[3])!=TxRxBuffer[4]){
        Result=vIC_Mifare1_Result_Error;
      }
    }else{
      Result=vIC_Mifare1_Result_Error;
    }
  }

  return Result;
}

//选卡操作
static int SelectCard_Sub(IC_Mifare1* _this,Hbyte CMD_Anticollision,Hbyte* Data,Hbyte* SAK){
  Hbyte TxRxBuffer[9];
  Hbyte RxBitLength;
  int Result;


  TxRxBuffer[0]=CMD_Anticollision;
  TxRxBuffer[1]=0x70U;
  TxRxBuffer[2]=Data[0];
  TxRxBuffer[3]=Data[1];
  TxRxBuffer[4]=Data[2];
  TxRxBuffer[5]=Data[3];
  TxRxBuffer[6]=TxRxBuffer[2]^TxRxBuffer[3]^TxRxBuffer[4]^TxRxBuffer[5];

  CalculateCRC_ToArray(TxRxBuffer,7U,&TxRxBuffer[7]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,72U,TxRxBuffer,24U,&RxBitLength,25);
  if(Result==vIC_Mifare1_Result_Ok){
    if(RxBitLength!=24U){
      Result=vIC_Mifare1_Result_Error;
    }else{
      if(CalculateCRC(TxRxBuffer,3)!=0U){
        Result=vIC_Mifare1_Result_Error;
      }
      SAK[0]=TxRxBuffer[0];
    }
  }

  return Result;
}

//防冲撞 并选卡
static int Anticollision(IC_Mifare1* _this,Hbyte* SAK,Hbyte* SerialNumber,int* SerialNumberLength){
  Hbyte Data[4];
  int Result;
  unsigned int Level;

  const unsigned char SEL_CMD[]={
    vIC_Mifare1_CMD_SEL_Level1,
    vIC_Mifare1_CMD_SEL_Level2,
    vIC_Mifare1_CMD_SEL_Level3
  };

  Level=0U;
  do{

    Result=Anticollision_Sub(_this,SEL_CMD[Level],Data);
    if(Result!=vIC_Mifare1_Result_Ok){
      return Result;
    }

    //成功 开始选定ID
    Result=SelectCard_Sub(_this,SEL_CMD[Level],Data,SAK);
    if(Result!=vIC_Mifare1_Result_Ok){
      return Result;
    }


    if((SAK[0]&0x04U)==0x00U){

      SerialNumber[Level*3+0]=Data[0];
      SerialNumber[Level*3+1]=Data[1];
      SerialNumber[Level*3+2]=Data[2];
      SerialNumber[Level*3+3]=Data[3];

      SerialNumberLength[0]=4+Level*3;

      return Result;
    }else{
      SerialNumber[Level*3+0]=Data[1];
      SerialNumber[Level*3+1]=Data[2];
      SerialNumber[Level*3+2]=Data[3];
    }

    Level++;
  }while(Level<3);

  return vIC_Mifare1_Result_Error;
}

//使卡进入停止状态
static int HaltCard(IC_Mifare1* _this){
  Hbyte TxRxBuffer[4];
  int Result;

  TxRxBuffer[0]=vIC_Mifare1_CMD_HLTA;
  TxRxBuffer[1]=0x00U;
  CalculateCRC_ToArray(TxRxBuffer,2U,&TxRxBuffer[2]);
  
  Result=_this->LL_Function.Transmit(_this->LL_Function.v,TxRxBuffer,32U,25);

  return Result;
}




//============================================================================================================================================
//
// 提供给外部的方法
//
//============================================================================================================================================

/**
 * @brief 初始化IC_Mifare1控制器
 * @param _this 未使用的句柄
 * @param LL_Function 底层方法集合
 * @return 无
 */
void IC_Mifare1_Init(IC_Mifare1* _this,IC_Mifare1_LL_Function* LL_Function){

  _this->LL_Function=LL_Function[0];
  _this->Status=vIC_Mifare1_Status_Ready;

}

/**
 * @brief 尝试进行一次卡操作 如果寻卡成功CommunicationCallback被调用 此后卡被halt
 * @param _this IC_Mifare1句柄
 * @param CommunicationCallback IC_Mifare1句柄
 * @param IsAll 0:仅选中空闲的卡 其他:所有卡都在选中范围
 * @return 0: CommunicationCallback成功被调用 其他:CommunicationCallback没有被调用
 */
int IC_Mifare1_Communication(IC_Mifare1* _this,void (*CommunicationCallback)(IC_Mifare1*,IC_Mifare1_CommunicationCallback_Param*),int IsAll){
  IC_Mifare1_CommunicationCallback_Param Param;
  Hbyte SerialNumber[10];
  int SerialNumberLength;
  int Result;

  if(_this->Status!=vIC_Mifare1_Status_Ready){
    
    if(_this->LL_Function.Reset(_this->LL_Function.v)!=vIC_Mifare1_Result_Ok){
      return -1;
    }

    _this->Status=vIC_Mifare1_Status_Ready;
  }

  //准备工作
  Result=_this->LL_Function.CallBeforeProbeCard(_this->LL_Function.v);
  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
    return -2;
  }


  //探测卡
  Result=Request(_this,IsAll,&Param.ATQA);
  if(Result!=vIC_Mifare1_Result_Ok){
    if(Result!=vIC_Mifare1_Result_NoCard){
      _this->Status=vIC_Mifare1_Status_CommunicationError;
    }else{
      if(_this->LL_Function.BspIsValid(_this->LL_Function.v)!=vIC_Mifare1_Result_Ok){
        _this->Status=vIC_Mifare1_Status_BspInvaild;
      }
    }

    return -3;
  }

  
  //防冲撞循环 返回选中卡的卡号
  Result=Anticollision(_this,&Param.SAK,SerialNumber,&SerialNumberLength);
  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
    return -4;
  }

  _this->Status=vIC_Mifare1_Status_Select;

  Param.SerialNumber=SerialNumber;
  Param.SerialNumberLength=SerialNumberLength;
  _this->Param=&Param;
  CommunicationCallback(_this,&Param);
  
  if(_this->Status==vIC_Mifare1_Status_Select){
    Result=HaltCard(_this);
    if(Result!=vIC_Mifare1_Result_Ok){
      _this->Status=vIC_Mifare1_Status_CommunicationError;
      
      return -5;
    }else{
      _this->Status=vIC_Mifare1_Status_Ready;

      //结束操作
      Result=_this->LL_Function.CallAfterHaltCard(_this->LL_Function.v);
      if(Result!=vIC_Mifare1_Result_Ok){
        _this->Status=vIC_Mifare1_Status_CommunicationError;
        return -6;
      }
    }
  }else{
    return -7;
  }
  
  
  return 0;
}




//============================================================================================================================================
//
// 提供给外部的方法 在IC_Mifare1_Communication()传入的CommunicationCallback()中调用
//
//============================================================================================================================================

/**
 * @brief 密钥验证
 * @param _this IC_Mifare1句柄
 * @param BlockAddr 要验证的块地址
 * @param AuthentType 密码类型 要验证的密码类型 vIC_Mifare1_AuthentType_A与vIC_Mifare1_AuthentType_B可选
 * @param Password 密钥
 * @return 返回执行结果
 */
int IC_Mifare1_Authent(IC_Mifare1* _this,Hbyte BlockAddr,int AuthentType,Hbyte* Password){
  int Result;

  if(_this->Status!=vIC_Mifare1_Status_Select){
    return vIC_Mifare1_Result_StatusError;
  }

  Result=_this->LL_Function.MFAuthent(_this->LL_Function.v,_this->Param->SerialNumber,BlockAddr,AuthentType,Password);
  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
  }

  return Result;
}

/**
 * @brief 读一个块
 * @param _this IC_Mifare1句柄
 * @param BlockAddr 块地址
 * @param Dst 指向用于存放数据的内存 大小16字节
 * @return 返回执行结果
 */
int IC_Mifare1_ReadBlock(IC_Mifare1* _this,Hbyte BlockAddr,Hbyte* Dst){
  Hbyte TxRxBuffer[18];
  Hbyte RxBitLength;
  int Result;
  int i;

  if(_this->Status!=vIC_Mifare1_Status_Select){
    return vIC_Mifare1_Result_StatusError;
  }

  TxRxBuffer[0]=vIC_Mifare1_CMD_Read;
  TxRxBuffer[1]=BlockAddr;
  CalculateCRC_ToArray(TxRxBuffer,2U,&TxRxBuffer[2]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,32U,TxRxBuffer,144U,&RxBitLength,10);
  if(Result==vIC_Mifare1_Result_Ok){
    if(RxBitLength==144U){
      if(CalculateCRC(TxRxBuffer,18)==0U){
        for(i=0;i<16;i++){
          Dst[i]=TxRxBuffer[i];
        }
      }else{
        Result=vIC_Mifare1_Result_Error;
      }
    }else{
      Result=vIC_Mifare1_Result_Error;
    }
  }

  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
  }

  return Result;
}

/**
 * @brief 写一个块
 * @param _this IC_Mifare1句柄
 * @param BlockAddr 块地址
 * @param SrcData 要写入的数据 大小16字节
 * @return 返回执行结果
 */
int IC_Mifare1_WriteBlock(IC_Mifare1* _this,Hbyte BlockAddr,Hbyte* SrcData){
  Hbyte TxRxBuffer[18];
  Hbyte RxBitLength;
  int Result;
  int i;

  if(_this->Status!=vIC_Mifare1_Status_Select){
    return vIC_Mifare1_Result_StatusError;
  }

  TxRxBuffer[0]=vIC_Mifare1_CMD_Write;
  TxRxBuffer[1]=BlockAddr;
  CalculateCRC_ToArray(TxRxBuffer,2U,&TxRxBuffer[2]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,32U,TxRxBuffer,4U,&RxBitLength,10);
  if(Result!=vIC_Mifare1_Result_Ok){
    goto Return;
  }
  if(RxBitLength!=4U){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }
  if((TxRxBuffer[0]&0xFU)!=0xAU){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }

  for(i=0;i<16;i++){
    TxRxBuffer[i]=SrcData[i];
  }
  CalculateCRC_ToArray(TxRxBuffer,16U,&TxRxBuffer[16]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,144U,TxRxBuffer,4U,&RxBitLength,15);
  if(Result!=vIC_Mifare1_Result_Ok){
    goto Return;
  }
  if(RxBitLength!=4U){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }
  if((TxRxBuffer[0]&0xFU)!=0xAU){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }

Return:
  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
  }
  return Result;
}

/**
 * @brief 数值块操作 数值块内的值 增加/减小/不加不减 到IC卡的数值缓冲区
 * @param _this IC_Mifare1句柄
 * @param BlockAddr IC_Mifare1句柄
 * @param IsDecrement 如果dValue不为0, 则该段有效: 0:加值 其他:减值
 * @param dValue 变化的值 如果为0 则使用Restore指令, 值不做变化的转到IC卡的数值缓冲区
 * @return 返回执行结果
 */
int IC_Mifare1_ValueOperation(IC_Mifare1* _this,Hbyte BlockAddr,int IsDecrement,Huint32 dValue){
  Hbyte TxRxBuffer[6];
  Hbyte RxBitLength;
  int Result;

  if(_this->Status!=vIC_Mifare1_Status_Select){
    return vIC_Mifare1_Result_StatusError;
  }

  if(dValue==0U){
    TxRxBuffer[0]=vIC_Mifare1_CMD_Restore;
  }else{
    if(IsDecrement!=0){
      TxRxBuffer[0]=vIC_Mifare1_CMD_Decrement;
    }else{
      TxRxBuffer[0]=vIC_Mifare1_CMD_Increment;
    }
  }
  
  TxRxBuffer[1]=BlockAddr;

  CalculateCRC_ToArray(TxRxBuffer,2U,&TxRxBuffer[2]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,32U,TxRxBuffer,4U,&RxBitLength,10);
  if(Result!=vIC_Mifare1_Result_Ok){
    goto Return;
  }
  if(RxBitLength!=4U){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }
  if((TxRxBuffer[0]&0xFU)!=0xAU){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }

  TxRxBuffer[0]=(Hbyte)(dValue&0xFFU);
  TxRxBuffer[1]=(Hbyte)((dValue>>8)&0xFFU);
  TxRxBuffer[2]=(Hbyte)((dValue>>16)&0xFFU);
  TxRxBuffer[3]=(Hbyte)((dValue>>24)&0xFFU);

  CalculateCRC_ToArray(TxRxBuffer,4U,&TxRxBuffer[4]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,48U,TxRxBuffer,4U,&RxBitLength,10);
  //对于Decrement/Increment/Restore指令 M1卡无响应 Transceive()会返回无卡结果 实际上这是正常的
  if(Result==vIC_Mifare1_Result_NoCard){
    Result=vIC_Mifare1_Result_Ok;
  }

Return:
  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
  }
  return Result;

}

/**
 * @brief 数值块操作 将IC卡的数值缓冲区的数值存储到块中
 * @param _this IC_Mifare1句柄
 * @param BlockAddr 要存储到的块地址
 * @return 返回执行结果
 */
int IC_Mifare1_ValueTransfer(IC_Mifare1* _this,Hbyte BlockAddr){
  Hbyte TxRxBuffer[4];
  Hbyte RxBitLength;
  int Result;

  if(_this->Status!=vIC_Mifare1_Status_Select){
    return vIC_Mifare1_Result_StatusError;
  }
  
  TxRxBuffer[0]=vIC_Mifare1_CMD_Transfer;
  TxRxBuffer[1]=BlockAddr;
  CalculateCRC_ToArray(TxRxBuffer,2U,&TxRxBuffer[2]);

  Result=_this->LL_Function.Transceive(_this->LL_Function.v,TxRxBuffer,32U,TxRxBuffer,4U,&RxBitLength,15);
  if(Result!=vIC_Mifare1_Result_Ok){
    goto Return;
  }
  if(RxBitLength!=4U){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }
  if((TxRxBuffer[0]&0xFU)!=0xAU){
    Result=vIC_Mifare1_Result_Error;
    goto Return;
  }

Return:
  if(Result!=vIC_Mifare1_Result_Ok){
    _this->Status=vIC_Mifare1_Status_CommunicationError;
  }
  return Result;
}




//============================================================================================================================================
//
// 附加给外部的方法 无调用条件 随便调用
//
//============================================================================================================================================

/**
 * @brief 生成数组块数据
 * @param BlockData 生成的数据存放位置
 * @param BlockAddr 块地址
 * @param Value 数值
 * @return 无
 */
void IC_Mifare1_MakeValueBlock(Hbyte* BlockData,Hbyte BlockAddr,Huint32 Value){

  BlockData[0]=(Hbyte)(Value&0xFFU);
  BlockData[1]=(Hbyte)((Value>>8)&0xFFU);
  BlockData[2]=(Hbyte)((Value>>16)&0xFFU);
  BlockData[3]=(Hbyte)((Value>>24)&0xFFU);

  BlockData[4]=~BlockData[0];
  BlockData[5]=~BlockData[1];
  BlockData[6]=~BlockData[2];
  BlockData[7]=~BlockData[3];

  BlockData[8]=BlockData[0];
  BlockData[9]=BlockData[1];
  BlockData[10]=BlockData[2];
  BlockData[11]=BlockData[3];

  BlockData[12]=BlockAddr;
  BlockData[13]=~BlockAddr;
  BlockData[14]=BlockAddr;
  BlockData[15]=~BlockAddr;

}

/**
 * @brief 简单解析并获取块的数值和地址域的地址 (有更好的恢复方法(只是恢复概率更高) 但这个函数没有使用 其实也没什么必要)
 * @param BlockData 块数据
 * @param BlockAddr 用于返回地址域的地址
 * @param Value 用于返回数值
 * @return 结果有效性
 */
Hbyte IC_Mifare1_ValueBlockGetValue(Hbyte* BlockData,Hbyte* BlockAddr,Huint32* Value){

  Huint32 valCnt[3][2];
  Hbyte addrCnt[4][2];
  int i;
  int j;
  int maxId;
  int maxVal;
  Hbyte Result;
  
  Result=0U;

  union{
    Hbyte _8;
    Huint32 _32;
  }temp;
  

  valCnt[0][1]=0;
  valCnt[1][1]=0;
  valCnt[2][1]=0;

  addrCnt[0][1]=0;
  addrCnt[1][1]=0;
  addrCnt[2][1]=0;
  addrCnt[3][1]=0;


  for(j=0;j<3;j++){

    temp._32=
      (((Huint32)BlockData[j*4+0])&0x000000FFU)
      |(((Huint32)(BlockData[j*4+1]<<8))&0x0000FF00U)
      |(((Huint32)(BlockData[j*4+2]<<16))&0x00FF0000U)
      |(((Huint32)(BlockData[j*4+3]<<24))&0xFF000000U);
    if(j==1){
      temp._32=~temp._32;
    }

    for(i=0;i<3;i++){
      if(valCnt[i][1]==0){
        valCnt[i][0]=temp._32;
        valCnt[i][1]=1;
        break;
      }else{
        if(valCnt[i][0]==temp._32){
          valCnt[i][1]++;
          break;
        }
      }
    }

  }

  for(j=0;j<4;j++){
    if(j%2==0){
      temp._8=BlockData[12+j];
    }else{
      temp._8=~BlockData[12+j];
    }
    
    for(i=0;i<4;i++){
      if(addrCnt[i][1]==0){
        addrCnt[i][0]=temp._8;
        addrCnt[i][1]=1;
        break;
      }else{
        if(addrCnt[i][0]==temp._8){
          addrCnt[i][1]++;
          break;
        }
      }
    }
  }

  maxVal=valCnt[0][1];
  maxId=0;
  for(j=1;j<3;j++){
    if(maxVal<valCnt[j][1]){
      maxVal=valCnt[j][1];
      maxId=j;
    }
  }
  if(maxVal<2){
    //无足够的数据确认数值
    Result|=vIC_Mifare1_ValueBlockGetValue_Value_Error;
  }else{
    if(maxVal!=3){
      //出现部分错误
      Result|=vIC_Mifare1_ValueBlockGetValue_Value_PartOk;
    }
  }
  

  Value[0]=valCnt[maxId][0];

  maxVal=addrCnt[0][1];
  maxId=0;
  for(j=1;j<4;j++){
    if(maxVal<addrCnt[j][1]){
      maxVal=addrCnt[j][1];
      maxId=j;
    }
  }
  if(maxVal<3){
    //无足够的数据确认块地址
    Result|=vIC_Mifare1_ValueBlockGetValue_Addr_Error;
  }
  if(maxVal!=4){
    //出现部分错误
    Result|=vIC_Mifare1_ValueBlockGetValue_Addr_PartOk;
  }

  BlockAddr[0]=addrCnt[maxId][0];

  return Result;
}

